<?php
/**
 * Project.php
 *
 * @copyright   2023 thingsworld.com.cn - All Rights Reserved
 * @link        http://thingsworld.com.cn/
 * @author      stiffer.chen <chenl@thingsworld.com.cn>
 * @created     2023-04-12 17:39:10
 * @modified    2023-04-12 17:39:10
 *
 */

namespace App\Models;

use App\Models\Project\History;
use App\Models\Project\Task;
use App\Repositories\ProjectRepo;
use App\Services\DeptService;
use Carbon\Carbon;

class Project extends BaseModel
{
    protected $table = 'project';
    protected $primaryKey = 'id';

    protected $fillable = [
        'project_number',
        'order_number',
        'name',
        'customer_id',
        'user_id',
        'zone_name',
        'province_id',
        'province_name',
        'city_id',
        'city_name',
        'county_id',
        'county_name',
        'address',
        'plan_start_at',
        'start_at',
        'plan_complete_at',
        'plan_work_hour',
        'closed_at',
        'entry_at',
        'status',
        'description',
        'mark',
        'create_user_id'
    ];

    protected $appends = [
        'status_text',
        'schedule',
        'schedule_text',
        'postpone',
        'plan_work_day',
        'show_start',
        'show_close',
        'show_modify',
        'show_delete',
        'show_complete',
        'show_add',
        'show_gantt',
        'show_restart',
        'show_filling',
        'is_charge_person'
    ];

    public function getShowStartAttribute()
    {
        if ($this->status == ProjectRepo::STATUS_UN_START) {
            return true;
        }
        return false;
    }

    public function getShowCloseAttribute()
    {
        if (in_array($this->status, [ProjectRepo::STATUS_UN_START, ProjectRepo::STATUS_STARTED, ProjectRepo::STATUS_COMPLETED])) {
            return true;
        }
        return false;
    }

    // 项目负责人、当前区域的区域经理、当前区域的区域主管可以修改
    // 当前区域是指当前项目的客户所属的区域
    public function getShowModifyAttribute()
    {
        // 当前登录用户ID
        $currentUserId = registry('user_id');
        // 当前用户所在区域
        $currentDeptId = registry('user')->dept_id;
        // 当前省份
        $currentCustomerId = $this->customer_id;
        // 用户权限判定
        $userCharge = false;
        if ($this->user_id == $currentUserId) {
            $userCharge = true;
        }
        // 当前客户所在区域
        if (is_charge($currentUserId) || is_manager($currentUserId)) {
//            $currentCustomer = Customer::find($currentCustomerId);
//            $currentCustomerDeptId = $currentCustomer->department_id ?? 0;
//            $parentDeptIds = (new DeptService())->getAllParentIds($currentCustomerDeptId);
//            $allDeptId = array_merge([$currentCustomerDeptId], $parentDeptIds);
//            if (in_array($currentDeptId, $allDeptId)) {
//                $userCharge = true;
//            }
            return true;
        }

        if ($userCharge && in_array($this->status, [ProjectRepo::STATUS_UN_START, ProjectRepo::STATUS_STARTED])) {
            return true;
        }
        return false;
    }

    public function getShowDeleteAttribute()
    {
        if (in_array($this->status, [ProjectRepo::STATUS_UN_START, ProjectRepo::STATUS_STARTED])) {
            return true;
        }
        return false;
    }

    public function getShowCompleteAttribute()
    {
        if (in_array($this->status, [ProjectRepo::STATUS_STARTED])) {
            return true;
        }
        return false;
    }

    public function getShowAddAttribute()
    {
        if ($this->status == ProjectRepo::STATUS_STARTED) {
            return true;
        }
        return false;
    }

    public function getShowGanttAttribute()
    {
        if (in_array($this->status, [ProjectRepo::STATUS_STARTED, ProjectRepo::STATUS_COMPLETED])) {
            return true;
        }
        return false;
    }

    public function getShowRestartAttribute()
    {
        if (in_array($this->status, [ProjectRepo::STATUS_CLOSED, ProjectRepo::STATUS_COMPLETED])) {
            return true;
        }
        return false;
    }

    public function getShowFillingAttribute()
    {
        if ($this->status == ProjectRepo::STATUS_COMPLETED) {
            return true;
        }
        return false;
    }

    public function getIsChargePersonAttribute()
    {
        $currentUserId = registry('user_id') ?? 0;
        if ($currentUserId == 1 || $currentUserId == $this->user_id) {
            return true;
        }
        return false;
    }

    public function getPlanWorkDayAttribute()
    {
        return Carbon::parse($this->plan_start_at)->diffInDays($this->plan_complete_at, true);
    }

    public function getStatusTextAttribute()
    {
        $status = $this->status;
        $params = collect(ProjectRepo::status())->keyBy('code')->toArray();
        $currentParam = $params[$status]['title'] ?? '';
        return $currentParam;
    }

    public function getScheduleAttribute()
    {
        $planStartAt = $this->plan_start_at;
        $planCompleteAt = $this->plan_complete_at;
        $now = Carbon::now()->toDateString();
        $status = $this->status;

        if ($status == ProjectRepo::STATUS_UN_START) {
            if ($planStartAt < $now) {
                return ProjectRepo::SCHEDULE_STATUS_UN_DELAY;
            } else {
                return ProjectRepo::SCHEDULE_STATUS_UN_START;
            }
        }
        if ($status == ProjectRepo::STATUS_STARTED) {
            if ($planCompleteAt < $now) {
                return ProjectRepo::SCHEDULE_STATUS_POSTPONE;
            } else {
                return ProjectRepo::SCHEDULE_STATUS_PROCESSING;
            }
        }
        if ($status == ProjectRepo::STATUS_CLOSED) {
            return '';
        }
        $histories = $this->histories->keyBy('status')->toArray();
        $completeHistory = $histories[ProjectRepo::STATUS_COMPLETED] ?? [];
        if (!$completeHistory) {
            return '';
        }
        $completeDate = Carbon::parse($completeHistory['create_time'])->toDateString();
        if ($completeDate < $planCompleteAt) {
            return ProjectRepo::SCHEDULE_STATUS_COMPLETE_BEFORE;
        } elseif ($completeDate == $planCompleteAt) {
            return ProjectRepo::SCHEDULE_STATUS_COMPLETE_EQUAL;
        } elseif ($completeDate > $planCompleteAt) {
            return ProjectRepo::SCHEDULE_STATUS_COMPLETE_AFTER;
        }
        return '';
    }

    public function getScheduleTextAttribute()
    {
        $schedule = $this->schedule;
        if ($schedule == '') {
            return '--';
        }
        $scheduleStatus = collect(ProjectRepo::scheduleStatus())->keyBy('code')->toArray();
        $currentScheduleStatus = $scheduleStatus[$schedule] ?? [];
        return $currentScheduleStatus['title'] ?? '';
    }

    public function getPostponeAttribute()
    {
        $status = $this->status;
        $planCompleteAt = $this->plan_complete_at;
        $now = Carbon::now()->toDateString();
        if ($status == ProjectRepo::STATUS_STARTED) {
            if ($planCompleteAt < $now) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    public function scopeByNumber($query, $number)
    {
        return $query->where('project_number', $number);
    }

    public function scopeByName($query, $name)
    {
        return $query->where('name', $name);
    }

    public function histories()
    {
        return $this->hasMany(History::class);
    }

    public function customer()
    {
        return $this->belongsTo(Customer::class);
    }

    public function user()
    {
        return $this->belongsTo(UserModel::class);
    }

    public function users()
    {
        return $this->hasMany(\App\Models\Project\User::class);
    }

    public function tasks()
    {
        return $this->hasMany(Task::class);
    }

    public function products()
    {
        return $this->hasMany(Product::class);
    }

    public function create_user()
    {
        return $this->belongsTo(UserModel::class, 'create_user_id');
    }
}